package middleware

import (
	"server/global"
	"server/myutils"
	"strings"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

var key = []byte(myutils.JWTKey)

type MyClaims struct {
	jwt.StandardClaims
	Username string `json:"username"`
	Role     int    `json:"role"`
}

func CreateToken(username string, role int) (token string, code int) {
	var MC = new(MyClaims)
	MC.Username = username
	MC.Role = role
	//有效期
	MC.ExpiresAt = time.Now().Add(time.Hour * time.Duration(myutils.ValidityPeriod)).Unix()
	//数据库
	MC.Issuer = myutils.DataBase
	//获取token
	t := jwt.NewWithClaims(jwt.SigningMethodHS256, MC)
	//转string-用key来加密-解密用key来解密
	s, err := t.SignedString(key)
	if err != nil {
		code = global.FAIL
		token = ""
		return
	}
	code = global.SUCCESS
	token = s
	return
}

func CheckToken(token string) (mc *MyClaims, code int) {
	settoken, _ := jwt.ParseWithClaims(token, &MyClaims{}, func(t *jwt.Token) (interface{}, error) {
		//Key来解密
		return key, nil
	})
	mc, cc := settoken.Claims.(*MyClaims)
	if cc && settoken.Valid {
		code = global.SUCCESS
		return
	} else {
		code = global.ERROR_TOKEN
		mc = nil
		return
	}
}

func JsonWebToken() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		//1.请求头获取token
		var token = ctx.Request.Header.Get("Authorization")
		if token == "" {
			myutils.ResultJSON(ctx, global.TOKEN_NULL, nil)
			ctx.Abort()
			return
		}
		//验证请求头格式
		var chtoken = strings.SplitN(token, " ", 2)
		if len(chtoken) != 2 || chtoken[0] != "Bearer" {
			myutils.ResultJSON(ctx, global.ERROR_TOKEN, nil)
			ctx.Abort()
			return
		}
		//token格式验证
		mc, code := CheckToken(chtoken[1])
		if code != global.SUCCESS {
			myutils.ResultJSON(ctx, global.ERROR_TOKEN, nil)
			ctx.Abort()
			return
		}
		//token过期验证
		if time.Now().Unix() >= mc.ExpiresAt {
			myutils.ResultJSON(ctx, global.TOKEN_RUNTIME_ERROR, nil)
			ctx.Abort()
			return
		}
		//挂载一个全局变量 ,username
		ctx.Set("username", mc.Username)
		ctx.Set("role", mc.Role)
		ctx.Next()
	}
}
